
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2008-2011, Salzburg Research. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * - Neither the name of the KiWi Project nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * Contributor(s):
 * Stefan
 *
 * File Info:
 * User: Stefan
 * Date: 2011/02/09
 * Time: 10:08
 *
 * Project: KiWi2, KiWi2 module
 */

/**
 * This widget allows to add, delete and alert configuration properties for kiwi2 core model.
 * The wiget uses jQuery and jQuery ui and is tested for jquery-1.4.4.min.js and jquery-ui-1.8.9.custom
 * in Firefox 3.6.13 and Safari 5.0.2.
 * The widget can be used via jQuery as follows:
 *    $('#content').systemconfig(options);
 * whereby options is a javascript object with value:
 *    host::String = defines the host where the application and the widgets run
 *    lang::"de"|"en"|x = defines the language (de and en are defines, all other languages can be defined via labels object)
 *    labels::object = labels in different languages (for more info have a look at codelines 288ff)
 */
$.kiwi2 = $.kiwi2 || {};
$.kiwiBaseUri = this.location.protocol + "//" + this.location.host + "/" + "KiWi2";
$.widget("kiwi2.spacesconfig", {
    /**
     * is called when widget gets initialized
     */
    _init: function(){
        this.initContainer();
        // for a second visiting of the site is it necessary to look
        if($("#dialogCategory").length == 0) {
            this.initCategoryDialog();
        } else {
            this.dialog = $("#dialogCategory");
        }
        this.initRemoveDialog();
        this.initAddSpaceDialog();
        this.writeContent();
    },

    /**
     * build html environment for the widget
     */
    initContainer: function() {
        var that = this;
        var widget = $("<div/>",{"class":"widget ui-widget"});
        this.contentBox = $("<div/>",{"class":"widget-content ui-widget-content","style":"height:300px"});
        this.contentBox.text(this.options.labels.loading[this.options.lang]);
        var headerBox = $("<div/>",{"class":"widget-header ui-widget-header"});
        var header = $("<h3/>");
        var buttons = $("<div/>",{"style":"float:right;margin-top:-18px;margin-right:2px;"});
        this.blinder = $("<button/>",{"class":"small-button"});
        this.blinder.text(this.options.labels.showhide[this.options.lang])
        //this.blinder.button({icons: {primary: "ui-icon-minus"},text:false});
        this.blinder.click(function(){
            that.hideContent();
        });
        buttons.append(this.blinder);
        header.text(this.options.labels.title[this.options.lang]);
        this.element.html("");
        widget.appendTo(this.element);
        headerBox.appendTo(widget);
        this.contentBox.appendTo(widget);
        header.appendTo(headerBox);
        buttons.appendTo(headerBox);
    },

    moveNodeTo : function(nodeValue, parentValue) {

        var backValue = true;
        var that = this;
        var parameter = "";

        if (parentValue) {
            parameter = "/" + parentValue
        }


        $.ajax({
            type:"POST",
            async:false,
            contentType: "application/json",
            url: that.options.host + "/kspace/space/update/category" + parameter + "?uri=" + nodeValue,
            success: function(result) {

                if (result.length == 0) {
                    backValue = false;
                }
            },
            error: function(jXHR) {
                backValue = false;
            }
        });

        return backValue;
    },

    /**
     * build a html environment for the dialog
     */
    initCategoryDialog: function() {
        this.dialogCategory = $("<div style='display:none' id='dialogCategory' />");
        this.dialogCategory.appendTo(this.element);
        this.dialogCategory.append("<p>Add a new category</p>");
        this.dialogCategory.append("<div><p>Titel: <input type='text' name='titleForm' id='categoryNameForm' value='category'/></p></div>");
    },

    /**
     * build a html environment for the dialog
     */
    initRemoveDialog: function() {
        this.dialogRemove = $("<div style='display:none' id='dialogRemove' />");
        this.dialogRemove.appendTo(this.element);
    },

    /**
     * build a html environment for the dialog
     */
    initAddSpaceDialog: function() {
        this.dialogSpace = $("<div style='display:none' id='dialogAddSpace' />");
        this.dialogSpace.appendTo(this.element);
        this.dialogSpace.append("<p>Add a new space</p>");
        this.dialogSpace.append("<div><p>Titel: <input type='text' name='titleForm' id='spaceNameForm' value='space'/></p></div>");
        this.dialogSpace.append("Type of ontology: ");

        var combo = $("<select name='typeForNewSpace' id='typeForNewSpaceID' />");

        this.dialogSpace.append(combo);

        combo.append("<option value='ontologyspace'>Ontologyspace</option>");
        combo.append("<option value='contentspace'>Contentspace</option>");
        combo.append("<option value='userspace'>Userspace</option>");
        combo.append("<option value='systemspace'>Systemspace</option>");
    },

    openRemoveSpaceDialog: function(category) {

        var that = this;

        var addRemoveSpace = function(uri) {

            var backValue = false

            if(!uri) return false;

            $.ajax({
                type:"DELETE",
                async:false,
                contentType: "application/json",
                url: that.options.host + "/kspace/space/remove?uri=" + uri,
                success: function(result) {

                    if (result.length != 0) {
                        $("#spacetree").jstree("remove");
                        backValue = true;
                    } else {
                        backValue = false;
                    }

                },
                error: function(jXHR) {
                    backValue = false;
                }
            });

            return backValue;
        };

        var that = this;
        this.dialogRemove.text("really remove the space?");
        this.dialogRemove.dialog({modal:true,
                            title: "Remove",
                            resizable: "Add space",
                            width: 400,
                            buttons:[{text:"No",click: function() {
                                that.dialogRemove.dialog("close");
                            }},{text:"Yes",click: function() {
                                console.log("here");

                                var node = $('#spacetree').jstree('get_selected');

                                addRemoveSpace($(node).attr("id"));

                                that.dialogRemove.dialog("close");
                            }}]
        });
    },

    openAddSpaceDialog: function(category, inst) {

        var that = this;

        var addSpaceViaWS = function(name, type) {
            var newThat = that;
            var backValue = false
            console.log("next")
            console.log(type);
            $.ajax({
                type:"PUT",
                async:false,
                contentType: "application/json",
                url: that.options.host + "/kspace/space/add/" + name + "?type=" + type,
                success: function(result) {

                    var parent = inst.get_json($('#spacetree').jstree('get_selected'), [ "id" , "type", "rel" ]);
                    var node = $('#spacetree').jstree('get_selected');

                    $('#spacetree').jstree('get_selected')

                    if (result.length == 0) {
                        backValue = false;
                    } else {
                        backValue = true;
                    }

                    if(node.length != 0) {

                        backValue = newThat.moveNodeTo(result.uri,parent[0].data);
                    } else if(result != null && result.length != 0) {

                        backValue = newThat.moveNodeTo(result.uri,null);
                    }

                },
                error: function(jXHR) {
                    backValue = false;
                }
            });

            return backValue;
        };

        //this.dialog.append("<div><p>Type: <input type='text' name='titleForm' id='titleForm' /></p></div>");
        this.dialogSpace.dialog({modal:true,
                            title: "Add Space",
                            resizable: false,
                            width: 400,
                            buttons:[{text:"Cancel",click: function() {
                                that.dialogCategory.dialog("close");
                            }},{text:"Add",click: function() {

                                if(addSpaceViaWS($("#spaceNameForm").val(), $("#typeForNewSpaceID").val())) {
                                   var uri = that.options.host + "/knowledgespace/" + $("#spaceNameForm").val();
                                   var type = that.options.space_ns + $("#typeForNewSpace").val;
                                   var rel = that.findRel(type);


                                   var treeNode = $("#spacetree").jstree("create", null, "last"
                                        , {attr : {id: uri, type: type}, data: $("#spaceNameForm").val()}, null, true);
                                   $(treeNode).attr("rel", rel);


                                }
                                that.dialogSpace.dialog("close");
                            }}]
        });
    },

    openAddCategoryDialog: function(selected, inst) {

        var that = this;

        var addCategorySpaceViaWS = function(name, type) {
            var newThat = that;
            var backValue = false
            $.ajax({
                type:"PUT",
                async:false,
                contentType: "application/json",
                url: that.options.host + "/kspace/space/add/" + name,
                success: function(result) {

                    var parent = inst.get_json($('#spacetree').jstree('get_selected'), [ "id" , "type", "rel" ]);
                    var node = $('#spacetree').jstree('get_selected');

                    $('#spacetree').jstree('get_selected')

                    if (result.length == 0) {
                        backValue = false;
                    } else {
                        backValue = true;
                    }

                    if(node.length != 0) {

                        backValue = newThat.moveNodeTo(result.uri,parent[0].data);
                    } else if(result != null && result.length != 0) {

                        backValue = newThat.moveNodeTo(result.uri,null);
                    }

                },
                error: function(jXHR) {
                    backValue = false;
                }
            });

            return backValue;
        };


        //this.dialog.append("<div><p>Type: <input type='text' name='titleForm' id='titleForm' /></p></div>");
        this.dialogCategory.dialog({modal:true,
                            title: "Add Category",
                            resizable: false,
                            width: 400,
                            buttons:[{text:"Cancel",click: function() {
                                that.dialogCategory.dialog("close");
                            }},{text:"Add",click: function() {

                                if(addCategorySpaceViaWS($("#categoryNameForm").val())) {
                                   var uri = that.options.host + "/categoryspace/" + $("#categoryNameForm").val();
                                   var type = that.options.space_ns + "categoryspace";
                                   var rel = "default";


                                   var treeNode = $("#spacetree").jstree("create", null, "last"
                                        , {attr : {id: uri, type: type}, data: $("#categoryNameForm").val()}, null, true);
                                   $(treeNode).attr("rel", rel);


                                }
                                that.dialogCategory.dialog("close");
                            }}]
        });

    },


    /**
     * send a DELETE to the configuration webservice (url is 'host'/core/config/data/'property')
     * @param property which should be deleted
     */
    deleteProperty: function(property) {
        var that = this;

        /**
         * send the HTTP DELETE:
         * success: -> if false is returned, do alert & close dialog
         * error: -> do alert & close dialog
         */
        $.ajax({
            type:"DELETE",
            url: that.options.host+"/core/config/data/"+property,
            success: function(result) {
                if(!result) alert("Could not delete property: internal error.")
                that.closeDialog();
            },
            error: function(jXHR) {
                alert(jXHR.statusText);
                that.closeDialog();
            }
        });
    },


    setType: function(nodeAndChilds) {

        var that = this;
        if (nodeAndChilds.attr.type === that.options.space_ns + "categoryspace") {
            nodeAndChilds.attr.rel = "default";
        } else if (nodeAndChilds.attr.type === that.options.space_ns + "ontologyspace") {
            nodeAndChilds.attr.rel = "ontologyspace";
        } else if (nodeAndChilds.attr.type === that.options.space_ns + "contentspace") {
            nodeAndChilds.attr.rel = "contentspace";
        } else if (nodeAndChilds.attr.type === that.options.space_ns + "userspace") {
            nodeAndChilds.attr.rel = "userspace";
        } else if (nodeAndChilds.attr.type === that.options.space_ns + "inferredspace") {
            nodeAndChilds.attr.rel = "inferredspace";
        } else if (nodeAndChilds.attr.type === that.options.space_ns + "systemspace") {
            nodeAndChilds.attr.rel = "systemspace";
        } else if (nodeAndChilds.attr.type === that.options.space_ns + "defaultspace") {
            nodeAndChilds.attr.rel = "defaultspace";
        } else {
            nodeAndChilds.attr.rel = "somethingelse";
        }
    },


    findRel: function(type) {

        var that = this;
        if (type === that.options.space_ns + "categoryspace") {
            return "default";
        } else if (type === that.options.space_ns + "ontologyspace") {
            return "ontologyspace";
        } else if (type === that.options.space_ns + "contentspace") {
            return "contentspace";
        } else if (type === that.options.space_ns + "userspace") {
            return "userspace";
        } else if (type === that.options.space_ns + "inferredspace") {
            return "inferredspace";
        } else if (type === that.options.space_ns + "systemspace") {
            return "systemspace";
        } else if (type === that.options.space_ns + "defaultspace") {
            return "defaultspace";
        } else {
            return "somethingelse";
        }
    },

    /**
     * get all properties and values and show them in a list, show also buttons for change operations
     */
    writeContent: function() {
        var that = this;
        var selected = null;
        var inst = null;

        var treeObject; // Object which stores the whole tree as jsonobject

        //asyn get of the tree structure and import in the tree
        $.get(that.options.host+"/kspace/space/tree",function(data){

            treeObject = buildTreeData(data);



            var tree = 	$("<div id='spacetree' />").bind("select_node.jstree", function(e, data) {

                var jsonObject = data.inst.get_json(data.rslt.obj, [ "id" , "type", "rel" ]);
                selected = data.rslt.obj;

                if(jsonObject[0].attr.rel !== "default") {
			        $('#categoryAddForm').attr('disabled', 'disabled');
                    $('#spaceAddForm').attr('disabled', 'disabled');
                } else {
                    $('#categoryAddForm').removeAttr('disabled');
                    $('#spaceAddForm').removeAttr('disabled');
                }

                console.log(jsonObject);

                //set Values for the right window
                $('#titelForm').val(jsonObject[0].data);
                $('#kindsForm').val(jsonObject[0].attr.rel === "default" ? "categoryspace" : jsonObject[0].attr.rel);

		    }).bind("loaded.jstree", function (event, data) {
                inst = data.inst;
            })
            .bind("create_node.jstree", function(e, data) {

                var jsonObject = data.inst.get_json(data.rslt.obj, [ "id" , "type", "rel" ]);
		    }).jstree(treeObject);

            console.log(treeObject);
            
            that.contentBox.html(tree);

        });

        //Build the tree data for the first representation of the tree
        //see the jstree.com documentation for a description of the format
        var buildTreeData = function(data) {

            var treeData = new Object;
            treeData.json_data = new Object;
            treeData.json_data.data = new Array(data.length);
            treeData.json_data.data = buildStructur(data, treeData.json_data.data, 0);

            // Import all important plugins
            treeData.plugins = new Array(6);
            treeData.plugins[0] = "themes";
            treeData.plugins[1] = "json_data";
            treeData.plugins[2] = "dnd";
            treeData.plugins[3] = "crrm";
            treeData.plugins[4] = "types";
            treeData.plugins[5] = "ui";

            // If someone click "Add Category"
            $("#categoryAddForm").click(function () {

                var nodeObject = that.openAddCategoryDialog(selected, inst);
            });

            // If someone click "Add Category"
            $("#removeForm").click(function () {

                var nodeObject = that.openRemoveSpaceDialog(selected, inst);
            });

            // If someone click "Add Space"
            $("#spaceAddForm").click(function () {

                var nodeObject = that.openAddSpaceDialog(selected, inst);
            });

            // extern drag and drop of a other tree is disable
            treeData.dnd = {
                                    "drop_target" : false,
                                    "drag_target" : false
                                };

            // check_mode and move_node method (Note it is modified the lib for the move_node method)
            treeData.crrm = {
                                "move" : {
                                    // show the green symbol for move a node by DND?
                                    "check_move" : function (m) {
                                        var parentNode = this.get_json(m.np, [ "id" , "type", "rel" ]);

                                        // Root and categoryspaces are OK!
                                        if(m.np.context.id) {
                                            return true;
                                        } else {
                                            if(parentNode[0].attr.type === that.options.space_ns + "categoryspace") {
                                                return true;
                                            }
                                            return false;
                                        }
                                    },
                                    //TODO: used .bind("move_node",...
                                    "move_node"	: function (obj, ref, position, is_copy, is_prepared, skip_check) {

                                       if(inst.get_json) {

                                           // Node element --> json element
                                           var parentNode = inst.get_json(obj.np, [ "id" , "type", "rel" ]);
                                           var node = inst.get_json(obj.o, [ "id" , "type", "rel" ]);

                                            if(obj.np.context.id) {
                                                return that.moveNodeTo(node[0].attr.id, null);
                                            } else {
                                                console.log(parentNode);
                                                console.log(node);
                                                return that.moveNodeTo(node[0].attr.id, parentNode[0].data);
                                            }
                                       }
                                    }
                                }
                            };

            // for all attr 'rel' a icon
            treeData.types = {
                                "valid_children" : [ "all" ],
                                "types" : {
                                    "contentspace" : {
                                        "icon" : {
                                            "image" : "icons/contentspace.png"
                                        }
                                    },
                                    "defaultspace" : {
                                        "icon" : {
                                            "image" : "icons/defaultspace.png"
                                        }
                                    },
                                    "inferredspace" : {
                                        "icon" : {
                                            "image" : "icons/inferredspace.png"
                                        }
                                    },
                                    "ontologyspace" : {
                                        "icon" : {
                                            "image" : "icons/ontologyspace.png"
                                        }
                                    },
                                    "somethingelse" : {
                                        "icon" : {
                                            "image" : "icons/somethingelse.png"
                                        }
                                    },
                                    "systemspace" : {
                                        "icon" : {
                                            "image" : "icons/systemspace.png"
                                        }
                                    },
                                    "userspace" : {
                                        "icon" : {
                                            "image" : "icons/userspace.png"
                                        }
                                    }
                                }
                            };



            return treeData;
        };

        // transfer the data in a object (first time deep is 0, it is for the revers)
        var buildStructur = function(data, object, deep) {
            

            for(var i=0; i<data.length; i++) {
                object[i] = new Object;

                object[i].attr = new Object;
                object[i].attr.id = data[i].uri;
                object[i].attr.type = data[i].type;
                that.setType(object[i]);

                object[i].data = data[i].titel;
                object[i].children = new Array(data[i].children.length);

                //if(data[i].children.length == 0 && deep != 0) {
                //    object[i] = data[i].titel;
                //}

                for(var t=0; t<data[i].children.length;t++) {
                    object[i].children = new Array(data[i].children[t].children.length);
                    object[i].children = buildStructur(data[i].children
                            , object[i].children, deep + 1);

                }

            }

            return object;
        };

    },

    /**
     * this are the options that customize the widget
     */
    options: {
	    host: $.kiwiBaseUri,
        labels: {"title":{"de":"Space-Konfiguration","en":"Space Configuration"},
                 "loading":{"de":"Laden...","en":"Loading..."},
                 "save_property":{"de":"Feldwerte speichern","en":"Save values"},
                 "add_value":{"de":"Wert hinzuf&uuml;gen","en":"Add value"},
                 "delete_value":{"de":"Wert l&ouml;schen","en":"Delete value"},
                 "removeTitle":{"de":"Feld l&ouml;schen:","en":"Delete property:"},
                 "removeContent":{"de":"Soll das Feld wirklich gel&ouml;scht werden?","en":"Do you want to delete this property"},
                 "saveTitle":{"de":"Feld speichern:","en":"Save property:"},
                 "saveContent":{"de":"Sollen die &Auml;nderungen wirklich gespeichert werden?","en":"Do you want save changings?"},
                 "ok":{"de":"OK","en":"OK"},
                 "cancel":{"de":"Abbrechen","en":"Cancel"},
                 "showhide":{"de":"Aus-/Einblenden","en":"Show/Hide"}},
        lang: "de",
        space_ns: "http://www.kiwi-project.eu/kiwi/core/knowledgespace#"
    }
});